{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a0126331",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入必要的库\n",
    "# LangChain相关：用于示例选择器、提示词模板构建\n",
    "from langchain_community.example_selectors import NGramOverlapExampleSelector\n",
    "from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate\n",
    "# 分词工具：jieba处理中文分词，nltk为英文分词（本示例用jieba）\n",
    "import jieba\n",
    "import ssl\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第一步：解决SSL证书问题（避免nltk/jieba下载数据时出错）\n",
    "# 临时禁用SSL验证（适用于网络环境限制场景）\n",
    "try:\n",
    "    # 创建未验证的SSL上下文\n",
    "    _create_unverified_https_context = ssl._create_unverified_context\n",
    "except AttributeError:\n",
    "    # 若环境不支持该方法，则不做处理（部分Python版本无此属性）\n",
    "    pass\n",
    "else:\n",
    "    # 覆盖默认的SSL上下文，禁用验证\n",
    "    ssl._create_default_https_context = _create_unverified_https_context\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第二步：定义核心示例数据（替换为「日常物品→场景分类」场景，更易理解）\n",
    "# 格式：{\"i\": 输入文本（待分类物品）, \"o\": 输出结果（分类标签）}\n",
    "examples = [\n",
    "    {\"i\": \"笔记本电脑\", \"o\": \"办公设备\"},\n",
    "    {\"i\": \"无线鼠标\", \"o\": \"办公设备\"},\n",
    "    {\"i\": \"篮球\", \"o\": \"运动器材\"},\n",
    "    {\"i\": \"瑜伽垫\", \"o\": \"运动器材\"},\n",
    "    {\"i\": \"红烧肉\", \"o\": \"中式菜肴\"},\n",
    "    {\"i\": \"麻婆豆腐\", \"o\": \"中式菜肴\"},\n",
    "    {\"i\": \"汉堡\", \"o\": \"西式快餐\"},\n",
    "    {\"i\": \"薯条\", \"o\": \"西式快餐\"},\n",
    "    {\"i\": \"防晒霜\", \"o\": \"护肤用品\"},\n",
    "    {\"i\": \"口红\", \"o\": \"护肤用品\"},\n",
    "    {\"i\": \"科幻小说\", \"o\": \"书籍读物\"},\n",
    "    {\"i\": \"漫画杂志\", \"o\": \"书籍读物\"}\n",
    "]\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第三步：创建基础提示词模板（定义单个示例的格式：输入→输出）\n",
    "# 模板作用：规定每个示例在最终提示词中的展示样式\n",
    "t1 = PromptTemplate.from_template(\n",
    "    \"输入：{i}\\n输出：{o}\"  # 换行分隔，更易读（原格式优化）\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第四步：中文分词处理（适配NGramOverlapExampleSelector的英文分词逻辑）\n",
    "# 核心原因：NGram算法默认按空格分割词汇，中文需先分词并加空格\n",
    "processed_examples = []  # 存储分词后的示例\n",
    "for example in examples:\n",
    "    # 对输入文本（i）进行中文分词，用空格连接结果（如\"笔记本电脑\"→\"笔记本 电脑\"）\n",
    "    processed_i = \" \".join(jieba.cut(example[\"i\"]))\n",
    "    # 输出结果（o）无需分词，直接保留\n",
    "    processed_o = example[\"o\"]\n",
    "    # 将处理后的输入输出加入新列表\n",
    "    processed_examples.append({\"i\": processed_i, \"o\": processed_o})\n",
    "\n",
    "# 打印原始示例和处理后示例（对比查看效果）\n",
    "print(\"=== 原始示例数据 ===\")\n",
    "for exp in examples:\n",
    "    print(exp)\n",
    "print(\"\\n=== 分词后示例数据（中文分词+空格连接）===\")\n",
    "for exp in processed_examples:\n",
    "    print(exp)\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第五步：初始化NGram重叠示例选择器（核心逻辑：按词汇重叠度筛选示例）\n",
    "s1 = NGramOverlapExampleSelector(\n",
    "    examples=processed_examples,  # 传入分词后的示例（必须，否则中文无法识别）\n",
    "    example_prompt=t1,  # 单个示例的展示模板（对应第三步的t1）\n",
    "    threshold=0.0,  # 筛选阈值：0.0表示排除与输入完全无重叠词汇的示例\n",
    "    # 补充说明：\n",
    "    # - 阈值<0：不排除任何示例，仅按重叠度排序\n",
    "    # - 阈值=0：排除完全无重叠的示例（本场景适用）\n",
    "    # - 阈值>0：仅保留重叠度≥阈值的示例（如0.5表示保留重叠度50%以上）\n",
    "    n=2  # 可选参数：n-gram的n值（默认2，即按2个连续词汇计算重叠度）\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第六步：构建少样本提示词模板（整合示例、前缀说明、后缀问题）\n",
    "fstp = FewShotPromptTemplate(\n",
    "    example_selector=s1,  # 关联示例选择器（动态筛选示例）\n",
    "    example_prompt=t1,    # 单个示例的格式模板\n",
    "    prefix=\"请按照以下示例的分类逻辑，对输入内容进行分类：\",  # 提示词前缀（任务说明）\n",
    "    suffix=\"输入：{i}\\n输出：\",  # 提示词后缀（用户问题，待模型填充输出）\n",
    "    input_variables=[\"i\"]  # 定义外部输入变量（仅需传入\"i\"，即待分类的内容）\n",
    ")\n",
    "\n",
    "# --------------------------------------------------\n",
    "# 第七步：测试效果（输入待分类词汇，生成最终提示词）\n",
    "# 测试用例：输入\"科幻漫画\"，查看筛选出的相关示例\n",
    "msg = fstp.format(i=\"科幻漫画\")\n",
    "print(\"\\n=== 最终生成的提示词 ===\")\n",
    "print(msg)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
